/*
 * Copyright 2010 Aekold Helbrass
 * 
 * This file is part of RosterComposer.
 * 
 * RosterComposer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * RosterComposer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with RosterComposer.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.heresylabs.rostercomposer;

import java.awt.BorderLayout;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.ToolTipManager;
import javax.swing.TransferHandler;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import org.heresylabs.rostercomposer.formatter.CompactFormatter;
import org.heresylabs.rostercomposer.roster.RosterEntry;

/**
 *
 * @author Aekold Helbrass <Helbrass@gmail.com>
 */
public class RosterPanel extends JPanel implements ListSelectionListener {

    private final JTable rosterTable;
    private final Composer composer;

    public RosterPanel(Composer composer, TableModel tableModel) {
        super(new BorderLayout());
        this.composer = composer;
        rosterTable = new RosterTable(tableModel);
        rosterTable.setFillsViewportHeight(true);
        rosterTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        rosterTable.getSelectionModel().addListSelectionListener(this);
        rosterTable.setTransferHandler(new RosterTransferHandler());
        ToolTipManager.sharedInstance().registerComponent(rosterTable);

        // fix columns width:
        {
            TableColumnModel columnModel = rosterTable.getColumnModel();
            // number:
            columnModel.getColumn(0).setMinWidth(60);
            // category:
            columnModel.getColumn(1).setMinWidth(100);
            // name:
            columnModel.getColumn(2).setMinWidth(120);
            // number:
            columnModel.getColumn(3).setMinWidth(60);
            // options:
            columnModel.getColumn(4).setPreferredWidth(Short.MAX_VALUE);
        }

        JScrollPane scroll = new JScrollPane(rosterTable);
        super.add(scroll, BorderLayout.CENTER);
        super.add(new RosterControlPanel(rosterTable, composer), BorderLayout.WEST);
    }

    @Override
    public void valueChanged(ListSelectionEvent e) {
        if (e.getValueIsAdjusting()) {
            return;
        }
        int row = rosterTable.getSelectedRow();
        if (row < 0) {
            return;
        }
        row = rosterTable.convertRowIndexToModel(row);
        composer.select(row);
    }

    private class RosterTable extends JTable {

        public RosterTable(TableModel dm) {
            super(dm);
        }

        @Override
        public String getToolTipText(MouseEvent event) {
            int row = rowAtPoint(event.getPoint());
            if (row < 0) {
                return null;
            }
            row = convertRowIndexToModel(row);
            RosterEntry entry = composer.getRosterEntry(row);
            StringBuilder sb = new StringBuilder(200);
            sb.append("<html><b>").append(entry.getUnit().getName()).append("</b>, ");
            sb.append(entry.getCategory().getName()).append("<br/>");
            sb.append(entry.getCost()).append(" <i>pts</i>");
            int number = entry.getNumber();
            if (number > 1) {
                sb.append(", ");
                sb.append(number);
                sb.append(" <i>models</i>");
            }
            String options = entry.getOptionsSummary();
            if (options != null) {
                sb.append("<br/>");
                sb.append(options);
            }
            return sb.toString();
        }

    }

    private class RosterTransferHandler extends TransferHandler {

        @Override
        public void exportToClipboard(JComponent comp, Clipboard clip, int action) throws IllegalStateException {
            if (action != COPY && action != MOVE && action != COPY_OR_MOVE) {
                return;
            }

            int[] selectedRows = rosterTable.getSelectedRows();
            if (selectedRows == null || selectedRows.length < 1) {
                return;
            }

            List<RosterEntry> roster = new ArrayList<RosterEntry>(selectedRows.length);
            // converting all rows to their model indexes:
            for (int i = 0; i < selectedRows.length; i++) {
                int r = rosterTable.convertRowIndexToModel(selectedRows[i]);
                RosterEntry entry = composer.getRosterEntry(r);
                roster.add(entry);
            }

            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            CompactFormatter formatter = new CompactFormatter(roster);
            formatter.setPrintTotal(false);
            formatter.write(writer);
            writer.flush();
            writer.close();
            clip.setContents(new StringSelection(stringWriter.toString()), null);
        }

    }

}
